package com.hcy.orderbusiness.Impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hcy.commonn.CommonInfoClient;
import com.hcy.mqclient.message.MessageServiceClient;
import com.hcy.order_domain.entity.OrderPayment;
import com.hcy.order_domain.entity.OrderRulePrice;
import com.hcy.order_domain.entity.ServerOrderStatistics;
import com.hcy.order_domain.service.IChargeRuleService;
import com.hcy.order_domain.service.IOrderPaymentService;
import com.hcy.order_domain.service.IOrderRulePriceService;
import com.hcy.order_domain.service.IServerOrderService;
import com.hcy.order_domain.service.impl.ServerOrderStatisticsServiceImpl;
import com.hcy.ordermodel.dto.request.*;
import com.hcy.ordermodel.dto.response.*;
import com.hcy.order_domain.entity.ServerOrder;
import com.hcy.orderbusiness.OptOrderBz;
import com.hcy.rabbitbasicmodel.enums.*;
import com.hcy.rabbitbasicmodel.model.ResponseData;
import com.hcy.rabbitbasicutils.utils.GaoDeUtils;
import com.hcy.rabbitbasicutils.utils.RedisUtils;
import com.hcy.rabbitbasicutils.utils.SnowFlake;
import com.hcy.userclient.client.UserInfoClient;
import com.hcy.usermodel.dto.request.CustomerInfoRequestDTO;
import com.hcy.usermodel.dto.response.CustomerInfoResponseDTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * @Author huchenying
 * @Description
 * @Date 2021/12/23 0:33
 */
@Service
public class OptOrderBzImpl implements OptOrderBz {

    Logger logger = LoggerFactory.getLogger(OptOrderBzImpl.class);

    @Autowired
    IServerOrderService orderService;
    @Autowired
    IOrderPaymentService orderPaymentService;
    @Autowired
    GaoDeUtils gaoDeUtils;
    @Autowired
    IOrderRulePriceService orderRulePriceService;
    @Autowired
    IChargeRuleService chargeRuleService;
    @Autowired
    CommonInfoClient commonInfoClient;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    MessageServiceClient messageServiceClient;
    @Autowired
    UserInfoClient userInfoClient;
    @Autowired
    ServerOrderStatisticsServiceImpl serverOrderStatisticsService;

    /**
     * @Author huchenying
     * @Description 创建一个初始订单，并计算初始价格
     * @Date 2021/12/23 0:38
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AddOrderResponseDTO createOrder(AddOrderRequestDTO requestDTO) {
        logger.info("do createOrder param -> {}", ToStringBuilder.reflectionToString(requestDTO));
        AddOrderResponseDTO responseDTO = new AddOrderResponseDTO();
        ServerOrder serverOrder = new ServerOrder();
        BeanUtils.copyProperties(requestDTO, serverOrder);
        serverOrder.setStartTime(new Date());
        boolean save = orderService.save(serverOrder);
        if (!save) {
            throw new RuntimeException("订单创建失败！");
        }
        BeanUtils.copyProperties(requestDTO, responseDTO);
        logger.info("res -> {}", ToStringBuilder.reflectionToString(responseDTO));
        return responseDTO;
    }

    /**
     * @Author huchenying
     * @Description 计算距离预估价格
     * @Date 2021/12/29 13:00
     **/
    @Transactional(rollbackFor = Exception.class)
    public void compute(OrderRulePrice orderRulePrice) {
        logger.info("计算距离预估价格 compute start");
        double dic = orderRulePrice.getTotalDistance();
        //计算分钟 默认 speed = 60 预估时间
        double v = dic / 20 * 60;
        orderRulePrice.setBaseMinute(v);
        orderRulePrice.setTotalTime(v);
        //计算价格
        //先写死 1公里以内5块 每m
        BigDecimal price;
        if (dic < 1) {
            price = new BigDecimal("5");
        } else {
            BigDecimal decimal = new BigDecimal("5");
            price = decimal.multiply(new BigDecimal(dic));
        }
        //向上取证的金额
        double money = price.setScale(0, BigDecimal.ROUND_UP).doubleValue();
        orderRulePrice.setBasePrice(money);
        orderRulePrice.setTotalPrice(money);
        //更新数据库
        boolean save = orderRulePriceService.save(orderRulePrice);
        if (!save) {
            throw new RuntimeException("添加失败！");
        }
    }

    /**
     * @Author huchenying
     * @Description 计算价格 。
     * @Date 2021/12/29 18:30
     **/
    public void computePrice(OrderRulePrice orderRulePrice) {

    }


    /**
     * @Author huchenying
     * @Description 司机接到乘客后 绑定轨迹并更新订单状态
     * @Date 2021/12/23 14:37
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SimpleOrderResponseDTO upDataOrderToStart(BindTrackRequestDTO requestDTO) {
        logger.info("更新订单 param = {}", ToStringBuilder.reflectionToString(requestDTO));
        LambdaQueryWrapper<ServerOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ServerOrder::getOrderNumber, requestDTO.getOrderNumber());
        ServerOrder serverOrder = orderService.getOne(wrapper);
        BeanUtils.copyProperties(requestDTO, serverOrder);
        serverOrder.setReceivePassengerTime(new Date());
        serverOrder.setStatus(OrderStatus.START_BUSINESS.getCode());
        serverOrder.setTrackId(requestDTO.getTrid());
        serverOrder.setTrackName(requestDTO.getTname());
        serverOrder.setOrderStartTime(new Date());
        if (!StringUtils.isEmpty(requestDTO.getTname())) {
            serverOrder.setTrackName(requestDTO.getTname());
        }
        boolean update = orderService.update(serverOrder, wrapper);
        if (!update) {
            throw new RuntimeException("订单更新失败");
        }
        // 填充价格信息表(略，先写死)
        // 获取车辆级别信息
        // 预估价格路程
        ResponseData<Integer[]> responseData1 = gaoDeUtils.directionShortest(serverOrder.getStartLongitude() + "," + serverOrder.getStartLatitude(), serverOrder.getEndLongitude() + "," + serverOrder.getEndLatitude());
        if (responseData1.getCode() != Code.Success) {
            throw new RuntimeException("计算距离价格等失败");
        }
        Integer[] data = responseData1.getData();
        OrderRulePrice orderRulePrice = new OrderRulePrice();
        Integer dic = data[0];
        Integer time = data[1];
        orderRulePrice.setTotalTime(time + 0d);
        orderRulePrice.setTotalPrice((double) (dic / 1000 * 2));
        orderRulePrice.setTotalDistance((double) (dic / 1000));
        orderRulePrice.setCarLevelId(1);
        orderRulePrice.setCarLevelName("普通型");
        orderRulePrice.setOrderNumber(serverOrder.getOrderNumber());
        boolean save = orderRulePriceService.save(orderRulePrice);
        if (!save) {
            throw new RuntimeException("价格预估失败");
        }
        SimpleOrderResponseDTO orderResponseDTO = new SimpleOrderResponseDTO();
        BeanUtils.copyProperties(serverOrder, orderResponseDTO);
        return orderResponseDTO;
    }

    /**
     * @Author huchenying
     * @Description 更新订单状态
     * @Date 2021/12/31 17:08
     **/
    @Override
    public SimpleOrderResponseDTO upDataOrderStatus(UpdateOrderRequestDTO requestDTO) {
        LambdaQueryWrapper<ServerOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ServerOrder::getOrderNumber, requestDTO.getOrderNumber());
        ServerOrder serverOrder = orderService.getOne(wrapper);
        BeanUtils.copyProperties(requestDTO, serverOrder);
        logger.info("更新订单 order = {}", ToStringBuilder.reflectionToString(serverOrder));
        boolean update = orderService.update(serverOrder, wrapper);
        if (!update) {
            throw new RuntimeException("订单更新失败");
        }
        SimpleOrderResponseDTO simpleOrderResponseDTO = new SimpleOrderResponseDTO();
        BeanUtils.copyProperties(serverOrder, simpleOrderResponseDTO);
        return simpleOrderResponseDTO;
    }

    /**
     * @Author huchenying
     * @Description 获取司机端首页信息,目前没有涉及到预约订单信息
     * @Date 2021/12/27 15:14
     **/
    @Override
    public HomeInfoResponseDTO findDriverHomeInfo(HomeInfoRequestDTO requestDTO) {
        HomeInfoResponseDTO responseDTO = serverOrderStatisticsService.getHomeStatistics(requestDTO.getDriverId());
        logger.info("首页信息 -> {}",ToStringBuilder.reflectionToString(requestDTO));
        //判断并获取当前单的信息
        if(org.apache.commons.lang.StringUtils.isNotEmpty(requestDTO.getOrderNumber())){
            //获取这个订单，判断状态和接单人是不是当前司机
            ResponseData<SimpleOrderResponseDTO> simpleOrder = getSimpleOrder(requestDTO.getOrderNumber());
            if(simpleOrder.getCode() != Code.Success){
                logger.warn("订单不存在！ orderNumber - > {}",requestDTO.getOrderNumber());
                responseDTO.setIsRuntime(false);
                return responseDTO;
            }
            SimpleOrderResponseDTO data = simpleOrder.getData();
            if(data.getStatus() < OrderStatus.RECV.getCode() || data.getStatus() > OrderStatus.ARRIVE.getCode()
            || !data.getDriverId().equals(requestDTO.getDriverId())){ //如果订单是已取消或者是未接单状态则不是司机的单,或者driverId不是
                responseDTO.setIsRuntime(false);
                //清除运力
                redisUtils.removeDriverRev(simpleOrder.getData().getDriverId().toString());
                return responseDTO;
            }
            OrderInfoResponseDTO orderInfoResponseDTO = new OrderInfoResponseDTO();
            BeanUtils.copyProperties(data,orderInfoResponseDTO);
            responseDTO.setIsRuntime(true);
            responseDTO.setCurrentOrder(orderInfoResponseDTO);
            return responseDTO;
        }
        responseDTO.setIsRuntime(false);
        return responseDTO;
    }
    /**
     * @Author huchenying
     * @Description 获取司机端首页信息
     * @Date 2021/12/27 15:14
     **/
    public HomeInfoResponseDTO findDriverHomeInfoBak(HomeInfoRequestDTO requestDTO) {
        //今日单量和今日流水
        HomeInfoResponseDTO responseDTO = orderService.getDriverTodayInfo(requestDTO);
        //当前司机接单 服务单，和预约单
        List<OrderInfoResponseDTO> orderInfoResponseDTOList = orderService.getDriverRecvOrderInfo(requestDTO);
        //根据订单状态找出当前的单
        Iterator<OrderInfoResponseDTO> iterator = orderInfoResponseDTOList.iterator();
        while (iterator.hasNext()) {
            OrderInfoResponseDTO next = iterator.next();
            //找出正在进行中的订单
            if (next.getStatus() > OrderStatus.RECV.getCode()) {
                //当前服务单
                responseDTO.setCurrentOrder(next);
                iterator.remove();
                break;
            }
        }
        //预约单
//        responseDTO.setAppointmentOrders(orderInfoResponseDTOList);
        logger.info("findDriverHomeInfo end result -> {}", ToStringBuilder.reflectionToString(responseDTO));
        return responseDTO;
    }

    /**
     * @Author huchenying
     * @Description 获取订单详情
     * @Date 2021/12/31 15:12
     **/
    @Override
    public OrderInfoResponseDTO getOrderDetails(DriverOrderRequestDTO requestDTO) {
        OrderInfoResponseDTO responseDTO = new OrderInfoResponseDTO();
        LambdaQueryWrapper<ServerOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServerOrder::getOrderNumber, requestDTO.getOrderNumber());
        ServerOrder one = orderService.getOne(queryWrapper);
        BeanUtils.copyProperties(one, responseDTO);
        return responseDTO;
    }

    /**
     * @Author huchenying
     * @Description 完成订单
     * @Date 2021/12/31 15:12
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SimpleOrderResponseDTO finishOrder(UpdateOrderRequestDTO requestDTO) {
        //获取当前订单
        LambdaQueryWrapper<ServerOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServerOrder::getOrderNumber, requestDTO.getOrderNumber());
        ServerOrder serverOrder = orderService.getOne(queryWrapper);
        //获取实际里程和时间  先使用预估的
//        ResponseData<TrackInfoResponseDTO> trackByTrid = gaoDeUtils.getTrackByTrid(serverOrder.getCarId(),serverOrder.getTrackId());
//        logger.info("获取当前订单轨迹信息 trackByTrid -> {}",ToStringBuilder.reflectionToString(trackByTrid));
//        if(trackByTrid.getCode() != Code.Success){
//            throw new RuntimeException(trackByTrid.getMsg());
//        }
//        TrackInfoResponseDTO trackInfo = trackByTrid.getData();
        //compute(orderRulePrice);
        //更新订单价格信息 直接用预估的省的算了
        LambdaQueryWrapper<OrderRulePrice> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(OrderRulePrice::getOrderNumber,serverOrder.getOrderNumber());
        OrderRulePrice one = orderRulePriceService.getOne(queryWrapper1);
        Double totalPrice = one.getTotalPrice();
        //生成交易单
        OrderPayment orderPayment = new OrderPayment();
        orderPayment.setOrderNumber(serverOrder.getOrderNumber());
        orderPayment.setTotalPrice(totalPrice);
        orderPayment.setPayNumber("J" + SnowFlake.getId());
        orderPayment.setCustomerId(serverOrder.getPassengerPhone());
        boolean save = orderPaymentService.save(orderPayment);
        if (!save) {
            throw new RuntimeException("交易单生成失败！");
        }
        //更新订单信息
        serverOrder.setStatus(OrderStatus.ARRIVE.getCode());
        serverOrder.setPassengerGetoffTime(new Date());
        serverOrder.setPassengerGetoffLatitude(requestDTO.getPassengerGetoffLatitude());
        serverOrder.setPassengerGetoffLongitude(requestDTO.getPassengerGetoffLongitude());
        //更新
        boolean update = orderService.update(serverOrder, queryWrapper);
        if (!update) {
            throw new RuntimeException("订单更新失败！");
        }
        //存入订单统计表
        ServerOrderStatistics serverOrderStatistics = new ServerOrderStatistics();
        serverOrderStatistics.setOrderNumber(serverOrder.getOrderNumber());
        serverOrderStatistics.setMoney(totalPrice);
        serverOrderStatistics.setDriverId(serverOrder.getDriverId());
        serverOrderStatistics.setDriverPhone(serverOrder.getDriverPhone());
        boolean save1 = serverOrderStatisticsService.save(serverOrderStatistics);
        if(!save1){
            throw new RuntimeException("订单统计保存失败！");
        }
        SimpleOrderResponseDTO simpleOrderResponseDTO = new SimpleOrderResponseDTO();
        BeanUtils.copyProperties(serverOrder, simpleOrderResponseDTO);
        return simpleOrderResponseDTO;
    }

    @Override
    public void autoCancelOrder(String orderNumber) {
        LambdaQueryWrapper<ServerOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServerOrder::getOrderNumber, orderNumber);
        ServerOrder one = orderService.getOne(queryWrapper);
        //如果订单还是预估状态就取消
        if (one.getStatus() == OrderStatus.START.getCode()) {
            one.setStatus(OrderStatus.CANCEL.getCode());
        }
        orderService.update(one, queryWrapper);
    }

    @Override
    public ResponseData<SimpleOrderResponseDTO> updateOrderForAddDriver(AddDriverForOrderRequestDTO requestDTO) {
        ResponseData<SimpleOrderResponseDTO> responseData = new ResponseData<>();
        //更新订单
        LambdaQueryWrapper<ServerOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServerOrder::getOrderNumber, requestDTO.getOrderNumber());
        ServerOrder serverOrder = orderService.getOne(queryWrapper);
        BeanUtils.copyProperties(requestDTO, serverOrder);
        boolean update = orderService.update(serverOrder, queryWrapper);
        if (update) {
            responseData.setCode(Code.Success);
            SimpleOrderResponseDTO simpleOrderResponseDTO = new SimpleOrderResponseDTO();
            BeanUtils.copyProperties(serverOrder, simpleOrderResponseDTO);
            responseData.setData(simpleOrderResponseDTO);
        } else {
            responseData.setCode(Code.Fail);
            responseData.setMsg("更新订单失败");
            logger.error("司机抢单,更新订单失败！");
        }
        return responseData;
    }

    @Override
    public ResponseData<SimpleOrderResponseDTO> getSimpleOrder(String orderNumber) {
        ResponseData<SimpleOrderResponseDTO> responseData = new ResponseData<>();
        LambdaQueryWrapper<ServerOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServerOrder::getOrderNumber, orderNumber);
        ServerOrder one = orderService.getOne(queryWrapper);
        if (one != null) {
            SimpleOrderResponseDTO simpleOrderResponseDTO = new SimpleOrderResponseDTO();
            BeanUtils.copyProperties(one, simpleOrderResponseDTO);
            responseData.setCode(Code.Success);
            responseData.setData(simpleOrderResponseDTO);
        } else {
            responseData.setCode(Code.Fail);
            responseData.setMsg("没有该订单");
        }
        return responseData;
    }

    @Override
    public SimpleOrderResponseDTO upDateOriginPoint(UpdateOrderOriginPointRequestDTO requestDTO) {
        LambdaQueryWrapper<ServerOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServerOrder::getOrderNumber, requestDTO.getOrderNumber());
        ServerOrder one = orderService.getOne(queryWrapper);
        BeanUtils.copyProperties(requestDTO, one);
        orderService.update(one, queryWrapper);
        SimpleOrderResponseDTO simpleOrderResponseDTO = new SimpleOrderResponseDTO();
        BeanUtils.copyProperties(one,simpleOrderResponseDTO);
        return simpleOrderResponseDTO;
    }

    @Override
    public ResponseData<OrderInfoResponseDTO> computerOrder(DriveComputerOrderRequestDTO requestDTO) {
        ResponseData<OrderInfoResponseDTO> responseData = new ResponseData<>();
        //先从缓存里拿订单，拿不到区去数据库拿
        SimpleOrderResponseDTO simpleOrder = null;
        String orderString = redisUtils.get("orderCache:" + requestDTO.getOrderNumber());
        if (orderString == null) {
            ResponseData<SimpleOrderResponseDTO> dtoResponseData = getSimpleOrder(requestDTO.getOrderNumber());
            simpleOrder = dtoResponseData.getData();
        } else {
            simpleOrder = JSONObject.parseObject(orderString, SimpleOrderResponseDTO.class);
        }
        OrderInfoResponseDTO orderInfoResponseDTO = new OrderInfoResponseDTO();
        BeanUtils.copyProperties(simpleOrder, orderInfoResponseDTO);
        logger.info("开始估算距离");
        try { //TODO 估算失败 BUG
            // 计算距离价格等
            String lat = requestDTO.getLat();
            String log = requestDTO.getLog();
            ResponseData<Integer[]> responseData1 = gaoDeUtils.directionShortest(requestDTO.getLog() + "," + requestDTO.getLat(), log + "," + lat);
            if (responseData1.getCode() != Code.Success) {
                throw new RuntimeException("计算距离价格等失败");
            }
            Integer dis = responseData1.getData()[0];
            //获取当前位置到乘客路程
            orderInfoResponseDTO.setDistance(dis + 0d);
            ResponseData<Integer[]> responseData2 = gaoDeUtils.directionShortest(simpleOrder.getStartLongitude() + "," + simpleOrder.getStartLatitude(), simpleOrder.getEndLongitude() + "," + simpleOrder.getEndLatitude());
            if (responseData1.getCode() != Code.Success) {
                throw new RuntimeException("获取当前位置到乘客路程失败");
            }
            //获取订单总里程
            Integer totalDis = responseData2.getData()[0];
            Integer time = responseData2.getData()[1]; //秒
            if (time < 60) {
                orderInfoResponseDTO.setTotalTime(1.0);
            } else {
                double mint = (time + 0d) / 60 + 1;
                orderInfoResponseDTO.setTotalTime(mint);
            }
            orderInfoResponseDTO.setTotalDistance(totalDis + 0d);
            //获取总价
            //TODO 价格计算
            if (totalDis < 1000) {
                orderInfoResponseDTO.setTotalPrice(5.0);
            } else {
                double money = (totalDis + 0d) / 5000 * 2;
                money = (double) Math.round(money * 10) / 10;
                if(money < 2){
                    money = 2.0;
                }
                orderInfoResponseDTO.setTotalPrice(money);
            }
        } catch (RuntimeException e) {
            logger.error("调用高德计算异常 e->{}", ToStringBuilder.reflectionToString(e));
        }
        //叫单时间
        try {
            SimpleDateFormat smd = new SimpleDateFormat("HH:mm:ss");
            String format = smd.format(simpleOrder.getStartTime());
            orderInfoResponseDTO.setStartTimeString(format);
        } catch (Exception e) {
            logger.error("时间格式化异常 e->{}", ToStringBuilder.reflectionToString(e));
        }
        responseData.setCode(Code.Success);
        responseData.setData(orderInfoResponseDTO);
        return responseData;
    }

    @Override
    public PayOrderResponseDTO notPayOrder(String customerId) {
        PayOrderResponseDTO responseDTO = new PayOrderResponseDTO();
        LambdaQueryWrapper<OrderPayment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderPayment::getCustomerId, customerId);
        queryWrapper.eq(OrderPayment::getStatus, 0);
        OrderPayment one = orderPaymentService.getOne(queryWrapper);
        logger.info("查找结果 -> {}", ToStringBuilder.reflectionToString(one));
        if (one == null) {
            responseDTO.setHaveFlag(false);
            return responseDTO;
        }
        responseDTO.setHaveFlag(true);
        BeanUtils.copyProperties(one, responseDTO);
        // 查找关联订单信息
        ResponseData<SimpleOrderResponseDTO> simpleOrder = getSimpleOrder(one.getOrderNumber());
        if (simpleOrder.getCode() != Code.Success) {
            throw new RuntimeException("未找到交易单号关联的订单信息");
        }
        BeanUtils.copyProperties(simpleOrder.getData(), responseDTO);
        logger.info("res -> {}", ToStringBuilder.reflectionToString(responseDTO));
        return responseDTO;
    }

    @Override
    public PayOrderResponseDTO getPayOrder(PayOrderRequestDTO requestDTO) {
        LambdaQueryWrapper<OrderPayment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(org.apache.commons.lang.StringUtils.isNotEmpty(requestDTO.getPayNumber()), OrderPayment::getPayNumber, requestDTO.getPayNumber());
        queryWrapper.eq(org.apache.commons.lang.StringUtils.isNotEmpty(requestDTO.getCustomerId()), OrderPayment::getCustomerId, requestDTO.getCustomerId());
        queryWrapper.eq(org.apache.commons.lang.StringUtils.isNotEmpty(requestDTO.getOrderNumber()), OrderPayment::getOrderNumber, requestDTO.getOrderNumber());
        queryWrapper.eq(requestDTO.getStatus() != null, OrderPayment::getStatus, requestDTO.getStatus());
        OrderPayment one = orderPaymentService.getOne(queryWrapper);
        PayOrderResponseDTO responseDTO = new PayOrderResponseDTO();
        BeanUtils.copyProperties(one, responseDTO);
        return responseDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SimpleOrderResponseDTO payOrder(PayOrderRequestDTO requestDTO) {
        //更新交易单信息
        LambdaQueryWrapper<OrderPayment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderPayment::getPayNumber, requestDTO.getPayNumber());
        OrderPayment one = orderPaymentService.getOne(queryWrapper);
        one.setStatus(1);
        one.setPayTime(new Date());
        one.setPayType(1);
        one.setPaidPrice(one.getTotalPrice());
        boolean save = orderPaymentService.update(one,queryWrapper);
        if (!save) {
            throw new RuntimeException("交易单更新失败");
        }
        LambdaQueryWrapper<ServerOrder> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(ServerOrder::getOrderNumber, one.getOrderNumber());
        ServerOrder serviceOne = orderService.getOne(queryWrapper1);
        serviceOne.setStatus(OrderStatus.PAYMENT.getCode());
        serviceOne.setPayType(1);
        serviceOne.setIsPaid(1);
        boolean save2 = orderService.update(serviceOne,queryWrapper1);
        if (!save2) {
            throw new RuntimeException("服务单单更新失败");
        }
        //请求user服务扣除余额
        CustomerInfoRequestDTO customerInfoRequestDTO = new CustomerInfoRequestDTO();
        customerInfoRequestDTO.setPhone(one.getCustomerId());
        customerInfoRequestDTO.setChangeCoin(-one.getTotalPrice());
        ResponseData<CustomerInfoResponseDTO> responseData = userInfoClient.changeCoin(customerInfoRequestDTO);
        if(responseData.getCode() != Code.Success){
            throw new RuntimeException(responseData.getMsg());
        }
//        //发送mq
//        Message message = new Message();
//        message.setTopic("moneyChange");
//        message.setKeys(one.getPayNumber());
//        message.setBody(String.valueOf(one.getTailPrice()).getBytes());
//        ResponseData<SendResult> responseData = messageServiceClient.pushSyncMessage0(message);
//        if(responseData.getCode() != Code.Success){
//            throw new RuntimeException("扣除余额消息发送失败！");
//        }
        SimpleOrderResponseDTO responseDTO = new SimpleOrderResponseDTO();
        BeanUtils.copyProperties(serviceOne,responseDTO);
        return responseDTO;
    }

    @Override
    public List<SimpleOrderResponseDTO> queryOrder(CustomerOrderListRequestDTO requestDTO) {
        List<SimpleOrderResponseDTO> responseDTOList = new ArrayList<>();
        LambdaQueryWrapper<ServerOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServerOrder::getPassengerPhone, requestDTO.getCustomerId());
        queryWrapper.in(CollectionUtils.isNotEmpty(requestDTO.getStatus()),ServerOrder::getStatus,requestDTO.getStatus());
        queryWrapper.orderBy(true,false,ServerOrder::getOrderStartTime);
        Page<ServerOrder> serverOrderPage = new Page<>();
        serverOrderPage.setSize(requestDTO.getPageSize());
        serverOrderPage.setCurrent(requestDTO.getPageNO());
        Page<ServerOrder> page = orderService.page(serverOrderPage, queryWrapper);
        List<ServerOrder> records = page.getRecords();
        for (ServerOrder record : records) {
            SimpleOrderResponseDTO simpleOrderResponseDTO = new SimpleOrderResponseDTO();
            BeanUtils.copyProperties(record,simpleOrderResponseDTO);
            responseDTOList.add(simpleOrderResponseDTO);
        }
        return responseDTOList;
    }

    @Transactional
    public SimpleOrderResponseDTO customerCancelOrder(String orderNumber) {
        //清除订单存活
        redisUtils.removeCallOrderKeepAlive(orderNumber);
        //更新状态
        LambdaQueryWrapper<ServerOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServerOrder::getOrderNumber, orderNumber);
        ServerOrder serviceOne = orderService.getOne(queryWrapper);
        serviceOne.setStatus(OrderStatus.CANCEL.getCode());
        boolean update = orderService.update(serviceOne, queryWrapper);
        if(!update){
            throw new RuntimeException("订单更新失败！");
        }
        SimpleOrderResponseDTO simpleOrderResponseDTO = new SimpleOrderResponseDTO();
        BeanUtils.copyProperties(serviceOne,simpleOrderResponseDTO);
        return simpleOrderResponseDTO;
    }

    @Override
    public SimpleOrderResponseDTO driverCancelOrder(String orderNumber) {
        boolean reCall = false;
        //更新状态
        LambdaQueryWrapper<ServerOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServerOrder::getOrderNumber, orderNumber);
        ServerOrder serviceOne = orderService.getOne(queryWrapper);
        if(serviceOne.getStatus() > OrderStatus.START_BUSINESS.getCode()){ //如果乘客已经上车，则不用让乘客端再次叫车
            reCall = true;
        }
        serviceOne.setStatus(OrderStatus.START.getCode());
        boolean update = orderService.update(serviceOne, queryWrapper);
        if(!update){
            throw new RuntimeException("订单更新失败！");
        }
        SimpleOrderResponseDTO simpleOrderResponseDTO = new SimpleOrderResponseDTO();
        BeanUtils.copyProperties(serviceOne,simpleOrderResponseDTO);
        return simpleOrderResponseDTO;
    }

    @Override
    public List<OrderInfoResponseDTO> getArriveOrderList(DriverOrderListRequestDTO requestDTO) {
        return orderService.getArriveOrderList(requestDTO);
    }
}
